<script setup lang="ts">
import { ref, watch } from 'vue';
import { testApi } from '@/service/api';
import { useBoolean } from '@sa/hooks';

defineOptions({
  name: 'ApiTestModal'
});

interface Props {
  apiId: number | null;
}

const props = defineProps<Props>();

const visible = defineModel<boolean>('visible', { required: true });

const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean();

const paramsInput = ref('{}');
const responseData = ref<any>(null);
const responseTime = ref<number>(0);

watch(visible, () => {
  if (visible.value) {
    paramsInput.value = '{}';
    responseData.value = null;
    responseTime.value = 0;
  }
});

async function handleTest() {
  if (!props.apiId) {
    window.$message?.error('API ID不能为空');
    return;
  }

  try {
    const params = JSON.parse(paramsInput.value);
    startLoading();
    const { data } = await testApi(props.apiId, params);
    if (data) {
      responseData.value = data;
      responseTime.value = data.responseTime || 0;
      if (data.code === 200) {
        window.$message?.success('测试成功');
      } else {
        window.$message?.error(data.message || '测试失败');
      }
    }
  } catch (error: any) {
    window.$message?.error(error.message || '参数格式错误');
  } finally {
    endLoading();
  }
}

function handleClose() {
  visible.value = false;
}
</script>

<template>
  <NModal v-model:show="visible" preset="card" title="API在线测试" style="width: 800px">
    <div class="flex-col gap-16px">
      <div>
        <div class="mb-8px font-medium">请求参数（JSON格式）</div>
        <NInput
          v-model:value="paramsInput"
          type="textarea"
          placeholder='{"id": 1, "name": "test"}'
          :rows="6"
          :disabled="loading"
        />
      </div>

      <NSpace justify="end">
        <NButton :loading="loading" type="primary" @click="handleTest">
          <icon-ic-round-play-arrow class="mr-4px text-20px" />
          执行测试
        </NButton>
      </NSpace>

      <div v-if="responseData">
        <div class="mb-8px flex items-center justify-between">
          <span class="font-medium">响应结果</span>
          <NTag :type="responseData.code === 200 ? 'success' : 'error'">
            {{ responseData.code === 200 ? '成功' : '失败' }} - {{ responseTime }}ms
          </NTag>
        </div>

        <NCard size="small">
          <div v-if="responseData.code === 200">
            <div class="mb-8px">
              <span class="font-medium">数据行数：</span>
              <span>{{ responseData.total }}</span>
            </div>
            <NDataTable
              :columns="[
                { key: 'index', title: '序号', width: 80, render: (_, index) => index + 1 },
                ...Object.keys(responseData.data[0] || {}).map(key => ({
                  key,
                  title: key,
                  ellipsis: { tooltip: true }
                }))
              ]"
              :data="responseData.data"
              :max-height="300"
              :scroll-x="800"
            />
          </div>
          <div v-else>
            <NAlert type="error" :title="responseData.message">
              {{ responseData.message }}
            </NAlert>
          </div>
        </NCard>
      </div>
    </div>

    <template #footer>
      <NSpace justify="end">
        <NButton @click="handleClose">关闭</NButton>
      </NSpace>
    </template>
  </NModal>
</template>
